package com.bike.bikeserver.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bike.bikeserver.common.core.domain.CommonResult;
import com.bike.bikeserver.common.enums.UserKey;
import com.bike.bikeserver.common.utils.TokenUtils;
import com.bike.bikeserver.domain.RewardsDetail;
import com.bike.bikeserver.domain.SysRole;
import com.bike.bikeserver.domain.WXUser;
import com.bike.bikeserver.mapper.RewardsDetailMapper;
import com.bike.bikeserver.mapper.SysRoleMapper;
import com.bike.bikeserver.mapper.WXUserMapper;
import com.bike.bikeserver.service.IWXUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;

import static com.bike.bikeserver.constant.Constants.*;

/**
 * @version 1.0
 * @Author ZZX
 * @Date 2023/7/8 22:00
 */
@Service
@Slf4j
public class WXUserServiceImpl implements IWXUserService
{
    @Autowired
    TokenUtils tokenUtils;
    @Autowired
    WXUserMapper wxUserMapper;
    @Autowired
    SysRoleMapper sysRoleMapper;
    @Autowired
    RewardsDetailMapper rewardsDetailMapper;

    @Override
    public CommonResult wxuserLogin(WXUser wxUser)
    {
        // 向微信API发送请求获取sessionKey和openId
        RestTemplate restTemplate = new RestTemplate();
        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("https://api.weixin.qq.com/sns/jscode2session").queryParam("appid", appId).queryParam("secret", appSecret).queryParam("js_code", wxUser.getWxcode()).queryParam("grant_type", grantType);
        String apiUrl = builder.toUriString();
        ResponseEntity<String> response = restTemplate.getForEntity(apiUrl, String.class);

        if (response.getStatusCode().is2xxSuccessful())
        {
            String responseBody = response.getBody();
            JSONObject res = JSONObject.parse(responseBody);
            String sessionKey = res.getString("session_key");
            String openid = res.getString("openid");
            // 将openid存在wxuser
            wxUser.setOpenid(openid);
            // 根据openid和sessionKey生成jwt
            Map<String, String> payload = new HashMap<>();
            payload.put("session_key", sessionKey);
            payload.put("openid", openid);
            // 将用户信息保存至数据库
            LambdaQueryWrapper<WXUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(WXUser::getOpenid, wxUser.getOpenid());
            WXUser wxUser1 = wxUserMapper.selectOne(wrapper);
            if (wxUser1 == null)
            {
                wxUserMapper.insert(wxUser);
                // 将用户加入权限表
                SysRole sysRole = new SysRole();
                sysRole.setUserSource(UserKey.FRONT.getValue());
                sysRole.setUserKey(wxUser.getOpenid());
                sysRole.setUserType(wxUser.getUserType());
                sysRole.setUserRight(USER_RIGHT_LOOK);
                sysRoleMapper.insert(sysRole);
                wxUser1 = wxUser;
            }
            StpUtil.login(FRONT_USER_PREFIX + wxUser1.getId());
            log.info("微信小程序用户【" + wxUser.getNickName() + "】于" + new Date() + "登录成功！");
            return CommonResult.success("登录成功", new HashMap<String, String>()
            {{
                put("token", StpUtil.getTokenValue());
            }});
        } else
        {
            return CommonResult.error(response.getBody());
        }
    }

    @Override
    public CommonResult wxuserLogout(String nickName)
    {
        // 根据nickName查找openid
        LambdaQueryWrapper<WXUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WXUser::getNickName, nickName);
        WXUser wxUser = wxUserMapper.selectOne(wrapper);
        // 移除token
        StpUtil.logout(FRONT_USER_PREFIX + wxUser.getId());
        log.info("微信小程序用户【" + nickName + "】于" + new Date() + "退出登录！");
        return CommonResult.success();
    }

    @Override
    public CommonResult getUserList()
    {
        List<WXUser> wxUserList = wxUserMapper.selectList(null);
        return CommonResult.success(wxUserList);
    }

    @Override
    public CommonResult getUserTypeByNickName(String nickName)
    {
        LambdaQueryWrapper<WXUser> wrapper_wxuser = new LambdaQueryWrapper<>();
        wrapper_wxuser.eq(WXUser::getNickName, nickName);
        WXUser wxUser = wxUserMapper.selectOne(wrapper_wxuser);
        return CommonResult.success("获取用户类型成功", wxUser.getUserType());
    }

    @Override
    public CommonResult getJoinTimeByNickName(String nickName)
    {
        LambdaQueryWrapper<WXUser> wrapper_wxuser = new LambdaQueryWrapper<>();
        wrapper_wxuser.eq(WXUser::getNickName, nickName);
        WXUser wxUser = wxUserMapper.selectOne(wrapper_wxuser);
        // 计算用户加入天数
        Date date1 = wxUser.getCreateTime(); // 第一个日期，Date 类型
        LocalDate localDate1 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); // 转换为 LocalDate

        LocalDate date2 = LocalDate.now(); // 第二个日期，当前日期

        long days = ChronoUnit.DAYS.between(localDate1, date2) + 1; // 计算两个日期之间的相差天数+1=加入天数

        // 获得积分数
        Integer score = wxUser.getScore();
        // 获得奖券总数
        LambdaQueryWrapper<RewardsDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RewardsDetail::getNickName, nickName);
        Integer count = rewardsDetailMapper.selectCount(wrapper);
        // 顺便更新用户的奖券总数字段，入库
        wxUser.setRewardsNum(count);
        wxUserMapper.updateById(wxUser);

        return CommonResult.success("操作成功", new HashMap<String, String>()
        {{
            put("joinTime", localDate1.toString());
            put("joinDays", String.valueOf(days));
            put("score", String.valueOf(score));
            put("rewardsNum", String.valueOf(count));
        }});
    }

    @Override
    public CommonResult editScore(WXUser wxUser)
    {
        // 判断积分是否为负
        if (wxUser.getScore() < 0)
        {
            return CommonResult.warn("积分数不得为负数！");
        }
        WXUser newUser = wxUserMapper.selectById(wxUser.getId());
        newUser.setScore(wxUser.getScore());
        int count = wxUserMapper.updateById(newUser);
        if (count != 0)
        {
            return CommonResult.success("积分修改成功！");
        }
        return CommonResult.error();
    }

    @Override
    public CommonResult deleteWXUser(WXUser wxUser)
    {
        /*加个权限删除*/
        WXUser wxUser1 = wxUserMapper.selectById(wxUser.getId());
        // 顺便删除微信用户对应的权限
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getUserKey, wxUser1.getOpenid());
        wrapper.eq(SysRole::getUserSource, "front");
        sysRoleMapper.delete(wrapper);
        int count = wxUserMapper.deleteById(wxUser.getId());
        if (count != 0)
        {
            return CommonResult.success("已成功删除该用户！");
        }
        return CommonResult.error();
    }

    @Override
    public CommonResult getUserLikeName(String nickName)
    {
        LambdaQueryWrapper<WXUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(WXUser::getNickName, nickName);
        List<WXUser> wxUsers = wxUserMapper.selectList(wrapper);
        return CommonResult.success("查询成功！为您找到" + wxUsers.size() + "条记录！", wxUsers);
    }
}